﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint.WebPartPages;
using System.Web.UI;
using System.Xml;
using Microsoft.SharePoint;
using System.ComponentModel;
using Microsoft.Office.Server;
//using Microsoft.Office.Server.UserProfiles;
using System.Xml.Serialization;
using VPLink2013.Framework;
using Microsoft.SharePoint.Utilities;
using System.Xml.Linq;
using Microsoft.SharePoint.WebControls;
using System.Web.UI.WebControls;
using System.Web;

namespace VPLink.WebParts
{
    /// <summary>
    /// Web Part that displays a customized announcement list.
    /// </summary>
    [ToolboxData("<{0}:AnnounceListViewWebPart runat=server></{0}:AnnounceListViewWebPart>"),
    XmlRoot(Namespace = "VPLink.WebParts")]
    public class AnnounceListViewWebPart : ListViewWebPart, IChangeableDisplayWebPart
    {
        private readonly int _listTemplate = 104;
        private readonly uint _defaultItemLimit = 100;
        private bool _behavior = false;
        //private uint _pageIndex = 1;
        private int _displayStyle;

        public override int ListTemplate
        {
            get { return _listTemplate; }
        }

        public AnnounceListViewWebPart()
        {
            dtStart = DateTime.Now;
            AddTrace("AnnounceListViewWebPart.Start");
        }

        #region IChangeableDisplayWebPart Members

        string[] IChangeableDisplayWebPart.DisplayStyleCollection
        {
            get
            {
                string[] displayStyleCollection = new string[11];

                displayStyleCollection[0] = "Titre et chapeau;0";
                displayStyleCollection[1] = "Titre et chapeau (sans date);1";
                displayStyleCollection[2] = "Titre et surtitre;2";
                displayStyleCollection[3] = "Titre et surtitre (sans date);3";
                displayStyleCollection[4] = "Titre et corps;4";
                displayStyleCollection[5] = "Titre et corps (sans date);5";
                displayStyleCollection[6] = "Photo et chapeau;6";
                displayStyleCollection[7] = "Corps;7";
                displayStyleCollection[8] = "Volet de visualisation;8";
                displayStyleCollection[9] = "Titre, surtitre et vignette;9";
                displayStyleCollection[10] = "Titre, surtitre et vignette (sans date);10";

                return displayStyleCollection;
            }
        }

        int IChangeableDisplayWebPart.DisplayStyle
        {
            get { return _displayStyle; }
            set { _displayStyle = value; }
        }

        #endregion

        [Browsable(true), Category("Miscellaneous"),
        WebPartStorage(Storage.Shared),
        FriendlyName("DisplayStyle"),
        Description("Query of the WebPart : the number of items to which the webpart is limited."),
        DefaultValue(0)]
        public int DisplayStyle
        {
            get { return _displayStyle; }
            set { _displayStyle = value; }
        }

        [Browsable(true), Category("Miscellaneous"),
        WebPartStorage(Storage.Shared),
        FriendlyName("Behavior"),
        Description("Behavior of the WebPart : publishing mode or list display mode."),
        DefaultValue(false)]
        public bool Behavior
        {
            get { return _behavior; }
            set { _behavior = value; }
        }

        protected SPListItemCollection CurrentUserListItems
        {
            get
            {
                AddTrace("CurrentUserListItems.Start");
                try
                {
                    if (_currentUserListItems == null)
                    {
                        // publishing mode (get items from root site)
                        if (_behavior)
                        {
                            AddTrace("CurrentUserListItems._behavior");
                            string url = SPContext.Current.Site.Url;
                            AddTrace("CurrentUserListItems.SPSite");
                            using (SPSite site = new SPSite(url))
                            {
                                AddTrace("CurrentUserListItems.SPWeb");
                                using (SPWeb web = site.RootWeb)
                                {
                                    AddTrace("CurrentUserListItems.RootWeb");
                                    SPList news = web.Lists["VP News"];
                                    AddTrace("CurrentUserListItems.SPList : VP News");
                                    _currentUserListItems = news.Items;
                                    AddTrace("CurrentUserListItems.SPList : Items");
                                }
                            }
                        }
                        else
                        {
                            AddTrace("CurrentUserListItems.ELSE _behavior");
                            if (_webID != null && _webID != Guid.Empty)
                            {
                                if (_listID != null && _listID != Guid.Empty)
                                {
                                    AddTrace("CurrentUserListItems.SPContext.Current.Site");
                                    using (SPWeb web = SPContext.Current.Site.OpenWeb(_webID))
                                    {
                                        AddTrace("CurrentUserListItems.OpenWeb");
                                        SPList news = web.Lists[_listID];
                                        AddTrace("CurrentUserListItems.SPList : " + news.Title);
                                        _currentUserListItems = news.Items;
                                        AddTrace("CurrentUserListItems.SPList : Items");
                                    }
                                }
                            }
                            else
                            {
                                if (_listID != null && _listID != Guid.Empty)
                                {
                                    AddTrace("CurrentUserListItems.SPContext.Current.Web");
                                    SPList news = SPContext.Current.Web.Lists[_listID];
                                    AddTrace("CurrentUserListItems.SPList : " + news.Title);
                                    _currentUserListItems = news.Items;
                                    AddTrace("CurrentUserListItems.SPList : Items");
                                }
                            }
                        }
                        AddTrace("CurrentUserListItems.Count : " + _currentUserListItems.Count.ToString());
                    }
                    return _currentUserListItems;
                }
                catch (Exception e)
                {
                    Log.Write(e.Message + "\r\n" + e.StackTrace, System.Diagnostics.EventLogEntryType.Error);
                }
                return null;
            }
        }

        override public ToolPart[] GetToolParts()
        {
            ToolPart[] toolParts = new ToolPart[6];
            toolParts[0] = new BehaviorToolPart();
            toolParts[1] = new ListViewToolPart();
            toolParts[2] = new FilterManagerToolPart();
            toolParts[3] = new ContentQueryToolPart();
            toolParts[4] = new DisplayManagerToolPart();
            toolParts[5] = new WebPartToolPart();
            return toolParts;
        }

        protected override void RenderWebPart(HtmlTextWriter output)
        {
            AddTrace("RenderWebPart.Start");

            try
            {
                if (CurrentUserListItems != null && CurrentUserListItems.Count > 0)
                {
                    AddTrace("RenderWebPart.CurrentUserListItems.Count : " + CurrentUserListItems.Count.ToString());

                    XmlDocument xmlDoc = new XmlDocument();
                    string strXmlListItems = "<xml xmlns:s='uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882' xmlns:dt='uuid:C2F41010-65B3-11d1-A29F-00AA00C14882' xmlns:rs='urn:schemas-microsoft-com:rowset' xmlns:z='#RowsetSchema'><rs:data>";
                    SPQuery query = new SPQuery();

                    query.Query = string.Empty;
                    if (!string.IsNullOrEmpty(_filterField1) && !string.IsNullOrEmpty(_filterType1) && !string.IsNullOrEmpty(_filterValue1))
                    {
                        if (!string.IsNullOrEmpty(_filterOperator) && !string.IsNullOrEmpty(_filterField2) &&
                           !string.IsNullOrEmpty(_filterType2) && !string.IsNullOrEmpty(_filterValue2))
                        {
                            query.Query += string.Format("<Where><{0}><{1}><FieldRef Name='{2}' /><Value Type='{3}'>{4}</Value></{1}><{5}><FieldRef Name='{6}' /><Value Type='{7}'>{8}</Value></{5}></{0}></Where>",
                                                         _filterOperator, _filterType1, _filterField1, _filterFieldType1, _filterValue1,
                                                         _filterType2, _filterField2, _filterFieldType2, _filterValue2);
                        }
                        else
                            query.Query += string.Format("<Where><{0}><FieldRef Name='{1}' /><Value Type='{2}'>{3}</Value></{0}></Where>", _filterType1, _filterField1, _filterFieldType1, _filterValue1);
                    }

                    if (!string.IsNullOrEmpty(_sortBy))
                        query.Query += string.Format("<OrderBy><FieldRef Name='{0}' Ascending=\"{1}\"/></OrderBy>", _sortBy, _sortOrder.ToString());
                    else
                        query.Query += string.Format("<OrderBy><FieldRef Name='Created' Ascending=\"{0}\"/></OrderBy>", _sortOrder.ToString());

                    AddTrace("RenderWebPart.query.Query : " + query.Query);

                    uint itemLimit = _isLimited ? _itemLimit : _defaultItemLimit;
                    AddTrace("RenderWebPart.itemLimit : " + itemLimit.ToString());

                    string strPage = ParamFrm("PageCrt");
                    AddTrace("RenderWebPart.strPage : " + strPage);

                    if (string.IsNullOrEmpty(strPage))
                    {
                        strPage = "1";
                    }
                    AddTrace("strPage : " + strPage);
                    int iPageCrt = int.Parse(strPage);
                    int iStart = (int)((iPageCrt - 1) * itemLimit + 1);
                    int iEnd = (int)(iPageCrt * itemLimit);
                    int iPageSuivante = 0;
                    int iPagePrecedente = 0;
                    bool blnPagePrecedente = false;
                    bool blnPageSuivante = false;

                    AddTrace("iPageCrt : " + iPageCrt.ToString()
                        + " / itemLimit : " + itemLimit.ToString()
                        + " / iStart : " + iStart.ToString()
                        + " / iEnd : " + iEnd.ToString());

                    AddTrace("Read from SPList : " + query.Query);
                    query.RowLimit = (uint)iEnd;
                    SPListItemCollection lic = CurrentUserListItems.List.GetItems(query);
                    AddTrace("Elements : " + lic.Count.ToString());

                    if (lic.Count > 0)
                    {
                        if (iEnd > lic.Count)
                        {
                            iEnd = lic.Count;
                        }
                        else
                        {
                            blnPageSuivante = true;
                            iPageSuivante = iPageCrt + 1;
                            AddTrace("PageSuivante");
                        }
                        if (iPageCrt > 1)
                        {
                            blnPagePrecedente = true;
                            iPagePrecedente = iPageCrt - 1;
                            AddTrace("PagePrecedente");
                        }

                        for (int i = iStart - 1; i < iEnd && i < lic.Count; i++)
                        {
                            if (_displayStyle == 8)
                            {
                                XmlDocument xmlItemDoc = new XmlDocument();
                                string xmlListItem = "<xml xmlns:s='uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882' xmlns:dt='uuid:C2F41010-65B3-11d1-A29F-00AA00C14882' xmlns:rs='urn:schemas-microsoft-com:rowset' xmlns:z='#RowsetSchema'><rs:data>";
                                xmlListItem += lic[i].Xml;
                                xmlListItem += "</rs:data></xml>";
                                xmlItemDoc.LoadXml(xmlListItem);
                                string xslItemDoc = SPContext.Current.Web.Url + "/_layouts/15/VPLink2013/XSL/Annonce/webpartAnnonceView.xsl";

                                XDocument xDocument = XDocument.Parse(lic[i].Xml);
                                xDocument.Root.SetAttributeValue("ows_Preview", SPEncode.UrlEncode(ListViewWebPart.SetXslTransformer(xslItemDoc, xmlItemDoc)));

                                strXmlListItems += xDocument.ToString(); ;
                            }
                            else
                                strXmlListItems += lic[i].Xml;
                        }
                    }
                    strXmlListItems += "</rs:data></xml>";
                    xmlDoc.LoadXml(strXmlListItems);
                    AddTrace("Load XML");

                    XmlNode nodeBaseUrl = xmlDoc.CreateNode(XmlNodeType.Element, "BaseUrl", "");
                    nodeBaseUrl.InnerText = !string.IsNullOrEmpty(_detailsPageUrl) ? _detailsPageUrl + "?ItemID=" : string.Empty;
                    xmlDoc.DocumentElement.AppendChild(nodeBaseUrl);

                    XmlNode nodeDisplayStyle = xmlDoc.CreateNode(XmlNodeType.Element, "DisplayStyle", "");
                    nodeDisplayStyle.InnerText = _displayStyle.ToString();
                    xmlDoc.DocumentElement.AppendChild(nodeDisplayStyle);

                    XmlNode nodeTitle = xmlDoc.CreateNode(XmlNodeType.Element, "Title", "");
                    nodeTitle.InnerText = this.Title;
                    xmlDoc.DocumentElement.AppendChild(nodeTitle);

                    XmlNode nodeNewFormURL = xmlDoc.CreateNode(XmlNodeType.Element, "NewFormURL", "");
                    if (CurrentUserListItems.List.DoesUserHavePermissions(SPBasePermissions.AddListItems))
                    {
                        nodeNewFormURL.InnerText = CurrentUserListItems.List.Forms[PAGETYPE.PAGE_NEWFORM].ServerRelativeUrl + "?Source=" + Page.Request.Path;
                    }
                    else
                    {
                        nodeNewFormURL.InnerText = "";
                    }
                    xmlDoc.DocumentElement.AppendChild(nodeNewFormURL);

                    XmlNode nodePageCrt = xmlDoc.CreateNode(XmlNodeType.Element, "PageCrt", "");
                    nodePageCrt.InnerText = strPage;
                    xmlDoc.DocumentElement.AppendChild(nodePageCrt);

                    if (blnPagePrecedente)
                    {
                        XmlNode nodeTitlePagePrec = xmlDoc.CreateNode(XmlNodeType.Element, "PagePrecedente", "");
                        nodeTitlePagePrec.InnerText = "javascript:setPage(" + iPagePrecedente.ToString() + ");";
                        xmlDoc.DocumentElement.AppendChild(nodeTitlePagePrec);
                    }
                    if (blnPageSuivante)
                    {
                        XmlNode nodeTitlePageSuiv = xmlDoc.CreateNode(XmlNodeType.Element, "PageSuivante", "");
                        nodeTitlePageSuiv.InnerText = "javascript:setPage(" + iPageSuivante.ToString() + ");";
                        xmlDoc.DocumentElement.AppendChild(nodeTitlePageSuiv);
                    }

                    if (this.TitleUrl != "")
                    {
                        XmlNode nodeTitleURL = xmlDoc.CreateNode(XmlNodeType.Element, "ListURL", "");
                        nodeTitleURL.InnerText = this.TitleUrl;
                        xmlDoc.DocumentElement.AppendChild(nodeTitleURL);
                    }

                    XmlNode nodeTrace = xmlDoc.CreateNode(XmlNodeType.Element, "PageName", "");
                    nodeTrace.InnerText = this.Context.Request.Url.AbsolutePath;
                    xmlDoc.DocumentElement.AppendChild(nodeTrace);

                    //XmlNode nodePageIndex = xmlDoc.CreateNode(XmlNodeType.Element, "PageIndex", "");
                    //nodePageIndex.InnerText = _pageIndex.ToString();
                    //xmlDoc.DocumentElement.AppendChild(nodePageIndex);

                    //XmlNode nodeAllowPaging = xmlDoc.CreateNode(XmlNodeType.Element, "AllowPaging", "");
                    //nodeAllowPaging.InnerText = _itemLimitType.ToString();
                    //xmlDoc.DocumentElement.AppendChild(nodeAllowPaging);


                    string strSuffix = this.DisplayStyle.ToString();
                    string strFileNameXSL = "webpartAnnonce" + strSuffix + ".xsl";
                    if (this.Context.Request.Url.AbsolutePath == "/Pages/default.aspx")
                    {
                        strFileNameXSL = "webpartAnnonceHome" + strSuffix + ".xsl";
                    }
                    WriteTraceXml(xmlDoc, strFileNameXSL.Replace(".xsl", ""));

                    AddTrace("Nom fichier XSL : " + strFileNameXSL);
                    string xslDoc = GetPathForXSL("Annonce",strFileNameXSL);
                    AddTrace("Ouverture fichier XSL");
                    string strXslTransformResult = ListViewWebPart.SetXslTransformer(xslDoc, xmlDoc);
                    AddTrace("Transformation XSL");
                    output.Write(strXslTransformResult);

                    AddTrace("this.Context.User.Identity.Name : " + this.Context.User.Identity.Name);

                    DateTime dtEnd = DateTime.Now;
                    TimeSpan tsTemps = dtEnd - dtStart;
                    AddTrace("Debut : " + dtStart.ToString("dd/MM/yyyy HH:mm:ss.fff"));
                    AddTrace("Fin   : " + dtEnd.ToString("dd/MM/yyyy HH:mm:ss.fff"));
                    AddTrace("Temps exec : " + tsTemps.Minutes + " minutes " + tsTemps.Seconds + " seconds "
                        + tsTemps.Milliseconds + " milliseconds");


                }
            }
            catch (Exception e)
            {
                AddTrace("Error : " + e.Message + "\r\n" + e.StackTrace);
            }
            //ContextTrace.Save(pathTemp, "webpartAnnonce");
        }

        /// <summary>
        ///	Uses Request.Form or Request.QueryString
        /// </summary>
        private string ParamFrm(string Name)
        {
            HttpRequest Request = Context.Request;
            string strValue;
            if (Request.Form.Count == 0)
            {
                strValue = Request.QueryString[Name];
            }
            else
            {
                strValue = Request.Form[Name];
                if (strValue == null || strValue == "undefined")
                {
                    strValue = Request.QueryString[Name];
                }
            }
            if (strValue == null || strValue == "undefined")
            {
                strValue = "";
            }
            strValue = strValue.Trim();

            if (strValue != "")
            {
                AddTrace("ParamFrm : " + Name + " = " + strValue);
            }
            return strValue;
        }

    }
}